home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1995 October
/
EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso
/
Aminet
/
comm
/
xeno
/
bbbbscd.lha
/
BBBBScd
/
Xenolink
/
Utilities
/
junkmail.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-25
|
8KB
|
346 lines
//
// junkmail.c by Alan Bland 9/25/92
//
// Sample source file for sending mail from a shell command.
//
// Requirements: SAS/C 5.10b, Xenolink Z.3a
//
// This source file is public domain and may be used for any purpose
// without permission of the author. The author claims no responsibility
// for the consequences of using this program.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <exec/types.h>
#include <exec/ports.h>
#include <exec/io.h>
#include <exec/semaphores.h>
#include <exec/libraries.h>
#include <dos/dos.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include "xenolink.h"
struct XenolinkBase *XenolinkBase;
#define MAX_ATTACH 30
#define MAX_RECIPIENTS 500
char *j_from = NULL;
char *j_to[MAX_RECIPIENTS];
short j_next_recipient = 0;
char *j_subject = NULL;
char *j_input = NULL;
char j_private = 0;
char *j_attach[MAX_ATTACH];
short j_next_attach = 0;
short j_base = -1;
int CXBRK(void) { return 0; }
int chkabort(void) { return 0; }
char *readinputfile(char *filename)
{
char *text;
char *bp;
FILE *f;
struct stat st;
// get file size and read in the file, converting \n to \r\n (hard newline)
if (stat(filename, &st) != 0) {
printf("File '%s' not found\n", filename);
return NULL;
}
// malloc an extra 4K to allow for \n to \r\n expansion
// SAS/C automatically frees this on exit
text = calloc(1, st.st_size + 4096);
if (!text) {
printf("Can't allocate %d bytes\n", st.st_size + 4096);
return NULL;
}
f = fopen(filename, "r");
if (!f) {
printf("Can't open '%s'\n", filename);
return NULL;
}
bp = text;
while (fgets(bp, 1000, f)) {
// fgets ends with \n, find it and convert
while (*bp && *bp != '\n') ++bp;
if (*bp) {
*bp++ = '\r';
*bp++ = '\n';
}
}
fclose(f);
return text;
}
//
// This function does all the nitty-gritty stuff for sending a message.
//
void xeno_send(char *from, char *to, char *MessageText, char *subject, short base,
short private, char *attach[], short num_attach)
{
struct Msg SaveMsg;
struct MsgSection *MsgSect;
struct ManagerSaveMsgCommand SaveCommand;
struct FidoNetAddress destination;
int i;
/* Start with a clean slate. */
ulibClearMem((void *)&SaveMsg, sizeof(SaveMsg));
MsgSect = ulibGetMsgSectionInfo(base);
if (!MsgSect) {
printf("Base %d is invalid\n", base);
return;
}
SaveMsg.Section = base;
SaveMsg.Flags.Private = private;
strncpy(SaveMsg.Subject, subject, SUBJECT_LENGTH);
strncpy(SaveMsg.From, from, USERNAME_LENGTH);
// copy recipient name, parsing out the netmail address if specified
ulibClearMem((void *)&destination, sizeof(destination));
for (i=0; i<USERNAME_LENGTH; ++i) {
if (to[i] == '@') {
destination.Zone = MsgSect->Zone;
if (ulibParseFidoNetAddress(&to[i+1], &destination)) {
printf("Fidonet address is invalid\n");
return;
}
SaveMsg.To[i] = 0;
break;
}
SaveMsg.To[i] = to[i];
if (!to[i]) break;
}
/* Date sent */
ulibStoreTodaysDate(&SaveMsg.DateSent);
/* Convert JONATHAN FORBES to Jonathan Forbes, etc. */
ulibNiceName(SaveMsg.To);
ulibNiceName(SaveMsg.From);
/* Netmail stuff -- could change this to get aka address for Orig... */
SaveMsg.OrigZone = MsgSect->Zone;
SaveMsg.OrigNet = MsgSect->Net;
SaveMsg.OrigNode = MsgSect->Node;
SaveMsg.OrigPoint = 0;
SaveMsg.DestZone = destination.Zone;
SaveMsg.DestNet = destination.Net;
SaveMsg.DestNode = destination.Node;
SaveMsg.DestPoint = destination.Point;
/* Better make sure destination address was given if this is netmail */
if (MsgSect->MsgSectionFlags.NetMail && destination.Zone == 0) {
printf("Destination address required for netmail section\n");
return;
}
/* Clear this structure so that no flags or anything else are set */
ulibClearMem((void *) &SaveCommand, sizeof(struct ManagerSaveMsgCommand));
SaveCommand.SaveMessage = &SaveMsg;
SaveCommand.Message = (void *) MessageText;
/* Construct Fidonet tag line */
SaveCommand.Flags.AppendOrigin = 1;
SaveCommand.Flags.CustomTagLine = 0;
SaveCommand.Flags.AddWaitingMessage = 1;
SaveCommand.Flags.AppendNetInfo = 1;
SaveCommand.SaveType = SAVETYPE_PROGRAM;
/* If SaveCommand.TextLength equals zero, then MT will perform a */
/* strlen() on your text to see how long it is. If TextLength is */
/* nonzero, then MT will use that value of TextLength as the length */
/* of the message text. This is simply a minor optimisation if you */
/* happen to know the length of your message beforehand. */
SaveCommand.TextLength = 0;
if (num_attach > 0) {
ulibSetMsgData(&SaveMsg, XMD_FLAGS_FILE_ATTACHED, 1);
}
ulibSaveMessage(&SaveCommand);
// NOTE: we do not update message counts written by the user!
if (num_attach > 0) {
char attname[100];
FILE *wp;
sprintf(attname, "%s%d.%d.attach", MsgSect->MsgSecDir,
base, SaveMsg.Number);
wp = fopen(attname, "w");
if (wp) {
for (i=0; i<num_attach; ++i) {
fprintf(wp, "%s\n", attach[i]);
}
fclose(wp);
}
}
printf("ok\n");
}
void usage(void)
{
printf("\nUsage: junkmail <options>\n\n"
"Required:\n"
" -f user Name of message author\n"
" -t user Name of message recipient (may be specified more than once)\n"
" For netmail recipients, include netmail address as follows:\n"
" -t \"The Cyborg@1:104/121.0\" (all one quoted string)\n"
" -s subject Subject of message\n"
" -i file Input file containing message text\n"
" -b number Number of message base to deposit message\n"
"\nOptional:\n"
" -p Private (default is public)\n"
" -a file File to attach (may be specified more than once)\n"
"\n");
exit(1);
}
void checkarg(char *opt, char *arg)
{
if (!arg || *arg == '-') {
printf("%s requires an argument\n", opt);
usage();
}
}
void main(int argc, char *argv[])
{
int i;
char *text;
// Parse the command line by brute force.
for (i=1; i<argc; ++i) {
char *opt;
char *arg;
opt = argv[i];
if (i < argc-1) {
arg = argv[i+1];
} else {
arg = NULL;
}
if (strcmp(opt, "-f") == 0) {
checkarg(opt, arg);
if (j_from) {
printf("Too many cooks!\n");
usage();
}
j_from = arg;
++i;
}
else if (strcmp(opt, "-t") == 0) {
checkarg(opt, arg);
if (j_next_recipient < MAX_RECIPIENTS) {
j_to[j_next_recipient++] = arg;
} else {
printf("Too many recipients!\n");
usage();
}
++i;
}
else if (strcmp(opt, "-s") == 0) {
checkarg(opt, arg);
if (j_subject) {
printf("What's the real subject?\n");
usage();
}
j_subject = arg;
++i;
}
else if (strcmp(opt, "-p") == 0) {
j_private = 1;
}
else if (strcmp(opt, "-a") == 0) {
FILE *f;
checkarg(opt, arg);
f = fopen(arg, "r");
if (!f) {
printf("Cannot attach '%s'\n", arg);
usage();
}
fclose(f);
if (j_next_attach < MAX_ATTACH) {
j_attach[j_next_attach++] = arg;
} else {
printf("Too many file attaches!\n");
usage();
}
++i;
}
else if (strcmp(opt, "-i") == 0) {
checkarg(opt, arg);
if (j_input) {
printf("Only one input file, please!\n");
usage();
}
j_input = arg;
++i;
}
else if (strcmp(opt, "-b") == 0) {
checkarg(opt, arg);
if (j_base >= 0) {
printf("Only one message base, please!\n");
usage();
}
j_base = atoi(arg);
++i;
}
else {
printf("Unrecognized option: %s\n", opt);
usage();
}
}
if (!j_from || j_next_recipient < 1 || !j_subject || !j_input || j_base < 0) {
usage();
}
if ((text = readinputfile(j_input)) == NULL) {
usage();
}
XenolinkBase = (struct XenolinkBase *) OpenLibrary("xenolink.library", 0);
if (!XenolinkBase) {
printf("Where's xenolink.library?\n");
exit(1);
}
#if DEBUG
printf("Base: %d\n", j_base);
printf("%s\n", j_private ? "Private" : "Public");
printf("From: %s\n", j_from);
for (i=0; i<j_next_recipient; ++i) printf(" To: %s\n", j_to[i]);
printf("Subj: %s\n", j_subject);
for (i=0; i<j_next_attach; ++i) printf(" Att: %s\n", j_attach[i]);
#endif
// Send the message to each recipient.
for (i=0; i<j_next_recipient; ++i) {
printf("Sending to %s...", j_to[i]);
xeno_send(j_from, j_to[i], text, j_subject, j_base, j_private,
j_attach, j_next_attach);
}
CloseLibrary((struct Library *) XenolinkBase);
exit(0);
}